package org.seven.jrdp.commons.shiro.realm;

import java.util.Collections;

import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.CredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.seven.jrdp.commons.shiro.model.User;
import org.seven.jrdp.commons.shiro.service.UserService;
import org.seven.jrdp.commons.util.CipherUtils;
import org.seven.jrdp.commons.util.ShiroUtils;

public class UserRealm extends AuthorizingRealm {
	private UserService userService;

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
		User user = ShiroUtils.getUser();
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		authorizationInfo.setStringPermissions(user.getPermissions());
		return authorizationInfo;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String account = (String) token.getPrincipal();
		String password = new String((char[]) token.getCredentials());
		User user = userService.getUserByAccount(account);
		if (user == null) {
			throw new AccountException();
		}
		if (!user.getPassword().equals(CipherUtils.md5(password, user.getId()))) {
			throw new CredentialsException();
		}
		user.setOrgan(userService.getOrganByUserId(user.getId()));
		if (user.isAdmin()) {
			user.setRoles(Collections.emptyList());
			user.setResources(userService.findResource());
		} else {
			user.setRoles(userService.findRoleByUserId(user.getId()));
			user.setResources(userService.findResourceByUserId(user.getId()));
		}
		ShiroUtils.setUser(user);
		return new SimpleAuthenticationInfo(user.getAccount(), user.getPassword(), ByteSource.Util.bytes(user.getId()), getName());
	}
}